﻿using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;

namespace Open.Data.Persistence
{
    public abstract class Literal<T> : Expression, ILiteral 
    {
        public T Value { get; set; }

        public Literal(T value)
        {
            Value = value;
        }

        public override IEnumerable<IParameter> GetParameters()
        {
            yield break;
        }

        public virtual string GetValue()
        {
            return string.Format("{0} ",Value.ToString());
        }
        
        public override void AppendHashCode(StringBuilder builder)
        {
            builder.Append(typeof(T).FullName);
            builder.Append(Value.ToString());
        }
    }

    public class StringLiteral : Literal<string>
    {
        public StringLiteral(string value) : base(value) { }

        public override string GetValue()
        {
            return string.Format("'{0}' ", Value.ToString());
        }
    }

    public class LongLiteral : Literal<long>
    {
        public LongLiteral(long value) : base(value) { }
    }

    public class IntegerLiteral : Literal<int>
    {
        public IntegerLiteral(int value) : base(value) { }
    }

    public class DateTimeLiteral : Literal<DateTime>
    {
        public DateTimeLiteral(DateTime value) : base(value) { }
    }

    public class BooleanLiteral : Literal<bool>
    {
        public BooleanLiteral(bool value) : base(value) { }
    }

    public class ByteLiteral : Literal<byte>
    {
        public ByteLiteral(byte value) : base(value) { }
    }
    
    public class ShortLiteral : Literal<short>
    {
        public ShortLiteral(short value) : base(value) { }
    }

    public class DoubleLiteral : Literal<double>
    {
        public DoubleLiteral(double value) : base(value) { }
    }

    public class FloatLiteral : Literal<float>
    {
        public FloatLiteral(float value) : base(value) { }
    }

    public class DecimalLiteral : Literal<decimal>
    {
        public int Precision { get; set; }
        public int Scale { get; set; }

        public DecimalLiteral(decimal value) : base(value) { }
        public DecimalLiteral(decimal value, int precision, int scale) : base(value) { }

        public override void AppendHashCode(StringBuilder builder)
        {
            builder.Append(typeof(decimal).FullName);
            builder.Append(Value.ToString());
            builder.Append(Precision.ToString());
            builder.Append(Scale.ToString());
        }
    }
}
